package cl.zeke.pizzastore.negocio.services.impl;

import cl.zeke.java.commons.util.CodecUtil;
import cl.zeke.pizzastore.dto.FiltroUsuariosDto;
import cl.zeke.pizzastore.finders.ClienteFinder;
import cl.zeke.pizzastore.finders.UsuarioFinder;
import cl.zeke.pizzastore.negocio.entities.Cliente;
import cl.zeke.pizzastore.negocio.entities.Usuario;
import cl.zeke.pizzastore.negocio.exceptions.EmailExistenteException;
import cl.zeke.pizzastore.negocio.exceptions.RunExistenteException;
import cl.zeke.pizzastore.negocio.services.UsuarioService;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
public class UsuarioServiceImpl implements UsuarioService {

    private static Logger log = LoggerFactory.getLogger(UsuarioServiceImpl.class);

    @PersistenceContext
    private EntityManager em;

    @Autowired
    private UsuarioFinder usuarioFinder;

    @Autowired
    private ClienteFinder clienteFinder;

    @Transactional(readOnly = false)
    @Override
    public Usuario guardarUsuario(Usuario usuario) {

        Usuario usuarioAux;
        Cliente clienteNuevo = usuario.getCliente();
        usuario.setCliente(null);

        //persistencia usuario
        usuarioAux = usuarioFinder.traerPorEmail(usuario.getEmail());
        if (usuarioAux != null && !usuarioAux.getIdUsuario().equals(usuario.getIdUsuario())) {
            throw new EmailExistenteException();
        }
        if (clienteNuevo != null) {

        }

        if (usuario.getIdUsuario() == null) {
            //hash password
            String hashpass = CodecUtil.generarHash(CodecUtil.TypeHash.MD5, usuario.getPassword());
            usuario.setPassword(hashpass);
            //activo
            usuario.setActivo(true);
            em.persist(usuario);
        } else {
            em.merge(usuario);
        }

        if (clienteNuevo == null) {
            return usuario;
        }

        //persistencia cliente
        clienteNuevo.setIdUsuario(usuario);
        Cliente clienteAux;
        clienteAux = clienteFinder.traerPorRun(clienteNuevo.getRun());
        if (clienteAux != null && !clienteAux.getIdCliente().equals(clienteNuevo.getIdCliente())) {
            throw new RunExistenteException();
        }

        if (clienteNuevo.getIdCliente() == null) {
            em.persist(clienteNuevo);
        } else {
            em.merge(clienteNuevo);
        }

        usuario.setCliente(clienteNuevo);
        return usuario;
    }

    @Transactional(readOnly = true)
    @Override
    public Usuario traerUsuarioConPerfilesPorEmailYPassword(String email, String password) {
        return usuarioFinder.traerConPerfilesPorEmailYPassword(email, password);
    }

    @Transactional(readOnly = true)
    @Override
    public Cliente traerClientePorUsuario(Usuario usuario) {
        return clienteFinder.traerPorUsuario(usuario);
    }

    @Transactional(readOnly = true)
    @Override
    public List<Usuario> traerTodosLosUsuarios() {
        return usuarioFinder.traerTodos();
    }

    @Transactional(readOnly = true)
    @Override
    public List<Usuario> buscarUsuarios(FiltroUsuariosDto filtro) {
        return usuarioFinder.buscar(filtro);
    }

    @Transactional(readOnly = false)
    @Override
    public void eliminar(Usuario usuario) {
        
        usuario = em.find(Usuario.class, usuario.getIdUsuario());
        
        //eliminar cliente
        if(usuario.getCliente()!=null) {
            em.remove(usuario.getCliente());
        }
        //eliminar usuario
        em.remove(usuario);
        
    }

}
